/*
 * bsp_flash_drievr.c
 *
 *  Created on: 2024��5��17��
 *      Author: wangang.chen
 */

#include "bsp_flash_driver.h"

flash_ssd_config_t flashSSDConfig;
uint8_t read_buff[32];
status_t ret;        /* Store the driver APIs return code */
uint32_t address;
flash_callback_t pCallBack;

/*!
  \brief Callback function for Flash operations
*/
START_FUNCTION_DEFINITION_RAMSECTION
void CCIF_Callback(void)
{
    /* Enable interrupt for Flash Command Complete */
    if ((FTFx_FCNFG & FTFx_FCNFG_CCIE_MASK) == 0u)
    {
        FTFx_FCNFG |= FTFx_FCNFG_CCIE_MASK;
    }
}
END_FUNCTION_DEFINITION_RAMSECTION


void EEPROM_Init(void)
{
    /* Always initialize the driver before calling other functions */
    ret = FLASH_DRV_Init(&Flash_InitConfig0, &flashSSDConfig);
    DEV_ASSERT(STATUS_SUCCESS == ret);

    /* Config FlexRAM as EEPROM if it is currently used as traditional RAM */
    if (flashSSDConfig.EEESize == 0u)
    {
        /* Configure FlexRAM as EEPROM and FlexNVM as EEPROM backup region,
         * DEFlashPartition will be failed if the IFR region isn't blank.
         * Refer to the device document for valid EEPROM Data Size Code
         * and FlexNVM Partition Code. For example on S32K144:
         * - EEEDataSizeCode = 0x02u: EEPROM size = 4 Kbytes
         * - DEPartitionCode = 0x08u: EEPROM backup size = 64 Kbytes */
        ret = FLASH_DRV_DEFlashPartition(&flashSSDConfig, 0x02u, 0x08u, 0x0u, false, true);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Re-initialize the driver to update the new EEPROM configuration */
        ret = FLASH_DRV_Init(&Flash_InitConfig0, &flashSSDConfig);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Make FlexRAM available for EEPROM */
        ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL);
        DEV_ASSERT(STATUS_SUCCESS == ret);
    }
    else    /* FLexRAM is already configured as EEPROM */
    {
        /* Make FlexRAM available for EEPROM, make sure that FlexNVM and FlexRAM
         * are already partitioned successfully before */
        ret = FLASH_DRV_SetFlexRamFunction(&flashSSDConfig, EEE_ENABLE, 0x00u, NULL);
        DEV_ASSERT(STATUS_SUCCESS == ret);
    }
}

status_t EEPROM_Write(uint32_t data_size, uint8_t *buff)
{

    /* Set callback function before a long time consuming flash operation
     * (ex: erasing) to let the application code do other tasks while flash
     * in operation. In this case we use it to enable interrupt for
     * Flash Command Complete event */
    pCallBack = (flash_callback_t)CCIF_Callback;
    flashSSDConfig.CallBack = pCallBack;

    /* Try to write data to EEPROM if FlexRAM is configured as EEPROM */
    if (flashSSDConfig.EEESize != 0u)
    {
#if 1
        address = flashSSDConfig.EERAMBase;
        ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, data_size, buff);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Verify the written data */
        if (*((uint32_t *)buff) != *((uint32_t *)address))
        {
            /* Failed to write data to EEPROM */
            return STATUS_ERROR;
        }

        /* Try to update one byte in an EEPROM address which isn't aligned */
        address = flashSSDConfig.EERAMBase;
        buff[0u] = 0xAFu;
        ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, data_size, buff);
        DEV_ASSERT(STATUS_SUCCESS == ret);

        /* Then verify */
        if (buff[0u] != *((uint8_t *)address))
        {
            /* Failed to update data to EEPROM */
        	return STATUS_ERROR;
        }
#endif
    }
    return ret;
}

status_t EEPROM_Read(uint32_t read_size)
{
  uint32_t addr;
  uint32_t i;
  addr = flashSSDConfig.EERAMBase;
	if (flashSSDConfig.EEESize != 0)
	{
		uint8_t *mem_addr = (uint8_t *)addr;

		for(i=0; i<read_size; i++)
		{
			read_buff[i] = mem_addr[i];
		}
	}
	return ret;
}
